package com.reverie.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reverie.config.CommonException;
import com.reverie.common.pojo.CommonPageReq;
import com.reverie.common.pojo.CommonResult;
import com.reverie.dto.user.UserQueryParam;
import com.reverie.entity.Menu;
import com.reverie.entity.User;
import com.reverie.service.IRoleMenuService;
import com.reverie.service.IUserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Rui.Zhou
 * @since 2024-02-03
 */
@RestController
@RequestMapping("/admin/v1/user")
public class UserController {
    @Resource
    private IUserService userService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private IRoleMenuService roleMenuService;

    @GetMapping("/getVerify")
    public CommonResult<Map<String,Object>> getVerify(HttpServletRequest request) {
        Map<String,Object> map = new HashMap<>();
        String tokenKey = RandomUtil.randomString(20);
        //定义图形验证码的长、宽、验证码字符数、干扰线宽度
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(140, 40, 4, 2);
        //获取验证码中的文字内容
        redisTemplate.opsForValue().set("login:verify:code:" + tokenKey,shearCaptcha.getCode(),1, TimeUnit.MINUTES);
        map.put("tk",tokenKey);
        String base64String = "";
        try {
            base64String = "data:image/png;base64," + shearCaptcha.getImageBase64();
            map.put("tv",base64String);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.data(map);
    }

    public static void main(String[] args) {
        String realPwd = MD5.create().digestHex(MD5.create().digestHex("kefu123456") + "2361");
        System.out.println(realPwd);
    }

    @PostMapping("save")
    public CommonResult<Boolean> onSave(@RequestBody User user) {
        if (user.getId() == null) {
            user.setCreateTime(LocalDateTime.now());
            user.setState(1);
            String rdmSalt = RandomUtil.randomString(4);
            user.setRdmSalt(rdmSalt);
            String realPwd = MD5.create().digestHex(MD5.create().digestHex("888888") + rdmSalt);
            user.setPassword(realPwd);
            user.setCreateUserId(Integer.valueOf(StpUtil.getLoginId().toString()));
        }
        return CommonResult.data(userService.saveOrUpdate(user));
    }

    @PostMapping("resetPwd")
    public CommonResult<Boolean> resetPwd(@RequestBody User user) {
        User oldUser = userService.getById(user.getId());
        if (oldUser != null) {
            oldUser.setPassword(MD5.create().digestHex("888888"));
        }
        return CommonResult.data(userService.updateById(oldUser));
    }

    @PostMapping("updatePwd")
    public CommonResult<Boolean> updatePwd(@RequestBody User user) {
        User oldUser = userService.getById(user.getId());
        if (oldUser != null) {
            String oldPwd = MD5.create().digestHex(MD5.create().digestHex(user.getOldPwd()) + oldUser.getRdmSalt());
            String newPwd = MD5.create().digestHex(MD5.create().digestHex(user.getNewPwd()) + oldUser.getRdmSalt());
            if (!oldPwd.equals(oldUser.getPassword())) {
                throw new CommonException("原密码错误");
            }
            if (newPwd.equals(oldUser.getPassword())) {
                throw new CommonException("新密码不能与旧密码相同");
            }
            oldUser.setPassword(newPwd);
        }
        return CommonResult.data(userService.updateById(oldUser));
    }

    @PostMapping("login")
    public SaResult login(@RequestBody User user, HttpServletRequest request) {

        if(!StringUtils.hasLength(user.getVerifyCode())){
            throw new CommonException("请输入验证码");
        }
        Object verifyCode = redisTemplate.opsForValue().get("login:verify:code:" + user.getVerifyTk());
        if(verifyCode == null){
            throw new CommonException("验证码已失效，请刷新页面");
        }
        if(!verifyCode.toString().equalsIgnoreCase(user.getVerifyCode())){
            throw new CommonException("验证码错误");
        }
        User accountUser = userService.getByUsername(user.getUsername());
        if (accountUser == null) {
            throw new CommonException("用户名不存在");
        }
        String password = MD5.create().digestHex(MD5.create().digestHex(user.getPassword()) + accountUser.getRdmSalt());
        if (accountUser.getPassword() != null && !accountUser.getPassword().equals(password)) {
            throw new CommonException("用户密码错误");
        }

        List<Menu> menuList = roleMenuService.listMenuTreeByUserId(accountUser.getId());
        accountUser.setRightMenus(menuList);
        StpUtil.login(accountUser.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        return SaResult.data(tokenInfo);
    }

    @PostMapping("queryPermissions")
    public CommonResult<List<String>> queryPermissions(@RequestBody UserQueryParam userQueryParam) {
        return CommonResult.data(StpUtil.getPermissionList(userQueryParam.getUserId()));
    }

    @PostMapping("queryMenuTree")
    public CommonResult<List<Menu>> queryMenuTree(@RequestBody UserQueryParam userQueryParam) {
        return CommonResult.data(roleMenuService.listMenuTreeByUserId(userQueryParam.getUserId()));
    }

    @PostMapping("page")
    public CommonResult<Page<User>> getPage(@RequestBody CommonPageReq<User> pageParam) {
        Page<User> users = userService.getPage(pageParam);
        buildRecords(users.getRecords());
        return CommonResult.data(users);
    }

    private void buildRecords(List<User> records) {
        if (!CollectionUtils.isEmpty(records)) {

        }
    }

    @PostMapping("delete")
    public CommonResult<Boolean> delete(@RequestBody User user) {
        return CommonResult.data(userService.removeById(user.getId()));
    }

}
